package pkg

import (
	"github.com/dgrijalva/jwt-go"
	"github.com/pkg/errors"
	"time"
)

type TokenPair struct {
	AccessToken  string
	RefreshToken string
}

// @secretKey: JWT 加解密密钥
// @iat: 时间戳
// @seconds: 过期时间，单位秒
// @payload: 数据载体
func SetJwtToken(payload string, accessTokenExpireTime, refreshTokenExpireTime int64) (TokenPair, error) {
	iat := time.Now().Unix()
	accessClaims := make(jwt.MapClaims)
	accessClaims["exp"] = iat + accessTokenExpireTime
	accessClaims["iat"] = iat
	accessClaims["payload"] = payload
	accessToken := jwt.NewWithClaims(jwt.SigningMethodHS256, accessClaims)
	accessToken.Claims = accessClaims
	accessTokenString, err := accessToken.SignedString([]byte("2201a"))
	if err != nil {
		return TokenPair{}, err
	}

	refreshClaims := make(jwt.MapClaims)
	refreshClaims["exp"] = iat + refreshTokenExpireTime
	refreshClaims["iat"] = iat
	refreshClaims["sub"] = payload
	refreshToken := jwt.NewWithClaims(jwt.SigningMethodHS256, refreshClaims)
	refreshToken.Claims = refreshClaims
	refreshTokenString, err := refreshToken.SignedString([]byte("2201a"))
	if err != nil {
		return TokenPair{}, err
	}
	return TokenPair{
		AccessToken:  accessTokenString,
		RefreshToken: refreshTokenString,
	}, err
}

// 解析token
func CheckJwtToken(tokenString string) (string, error) {
	token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
		return []byte("2201a"), nil
	})
	if err != nil {
		return "", errors.New("token解析失败")
	}
	if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
		return claims["payload"].(string), nil
	}
	return "", errors.New("token解析失败")
}
func RefreshJwtToken(refreshTokenString string, newAccessTokenExpireTime int64) (string, error) {
	token, err := jwt.Parse(refreshTokenString, func(token *jwt.Token) (interface{}, error) {
		return []byte("2201a"), nil
	})
	if err != nil {
		return "", errors.New("token解析失败")
	}
	if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
		if sub, ok := claims["sub"].(string); ok {
			iat := time.Now().Unix()
			accessClaims := make(jwt.MapClaims)
			accessClaims["exp"] = iat + newAccessTokenExpireTime
			accessClaims["iat"] = iat
			accessClaims["payload"] = sub
			newAccessToken := jwt.NewWithClaims(jwt.SigningMethodHS256, accessClaims)
			return newAccessToken.SignedString([]byte("2201a"))
		}
		return "", errors.New("无效的负荷")
	}
	return "", errors.New("无效的令牌")
}
